package com.spiro.gis.tiledownload.common;

import com.spiro.gis.tiledownload.TileCoordinate;
import com.spiro.gis.tiledownload.https.CustomTrustManager;
import com.spiro.gis.tiledownload.https.IgnoreHostnameVerifier;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: Shaoping Huang
 * @Description:
 * @Date: 1/15/2018
 */
public class HttpUtils {

    static {
        TrustManager[] tms = new TrustManager[1];
        TrustManager tm = new CustomTrustManager();
        tms[0] = tm;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, tms, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new IgnoreHostnameVerifier());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
            "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";

    public static final Pattern IMAGE_CONTENT_TYPE_REG = Pattern.compile("image\\/(\\w+) *;?");
    public static String getSuffix(String contentType) {
        if (contentType == null) {
            return null;
        }

        String suffix = null;

        Matcher matcher = IMAGE_CONTENT_TYPE_REG.matcher(contentType);
        while (matcher.find()) {
            suffix = matcher.group(1);
            break;
        }

        if (suffix != null) {
            suffix = "." + suffix;
        }

        return suffix;
    }

    public static String getContentType(String testUrl) {
        try {
            URL url = new URL(testUrl);
            URLConnection conn = url.openConnection();
            conn.setRequestProperty("User-Agent", USER_AGENT);
            conn.setRequestProperty("Accept", "image/webp,image/apng,image/*,*/*;q=0.8");
            conn.setRequestProperty("Connection", "keep-alive");

            conn.connect();
            return conn.getContentType();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void downloadImgToPath(String imgHttpUrl, String targetPath) throws IOException {
        File targetFile = new File(targetPath);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        File parentDir = targetFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }

        URL url = new URL(imgHttpUrl);
        InputStream in = null;
        FileOutputStream fos = null;

        try {
            URLConnection conn = url.openConnection();
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
            conn.setRequestProperty("Accept", "image/webp,image/apng,image/*,*/*;q=0.8");
            conn.setRequestProperty("Connection", "keep-alive");

            // Add readTimeout
            conn.setConnectTimeout(2000);
            conn.setReadTimeout(5000);
            conn.connect();
            in = conn.getInputStream();
            fos = new FileOutputStream(targetPath);

            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

        } finally {

            if (in != null) {
                in.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }

    public static final String Z_REG = "\\{ *z *\\}";
    public static final String X_REG = "\\{ *x *\\}";
    public static final String Y_REG = "\\{ *y *\\}";

    public static String buildImgUrl(String urlPattern, TileCoordinate tc) {
        String url = urlPattern;
        url = url.replaceAll(Z_REG, Integer.toString(tc.getZ()));
        url = url.replaceAll(X_REG, Integer.toString(tc.getX()));
        url = url.replaceAll(Y_REG, Integer.toString(tc.getY()));
        return url;
    }
}
